#!/usr/bin/python
# -*- coding: utf-8 -*-

"""
This module provides Plugin class
"""

__all__ = ['Plugin', 'available_plugins']

import os
import sys


from _pylot.core.path import Path
from _pylot.core.system import ENCODING
from _pylot.defaultconf import hardbook
from _pylot.core.utils import uprint

def available_plugins(guiflag):
  plugin_list = []
  for plugin in hardbook(u'plugins').listdir() :
    if not plugin.name.startswith(u'.') and plugin.isdir():
      try :
        module = Plugin(plugin.name, guiflag)
      except ImportError:
        pass
      else :
        plugin_list.append(plugin.name)
        del module
  return plugin_list

class Plugin (object) :
  u"""
  This class represents a plugin.

  It provides following attributes :

    - cli_mod : CLI module of plugin  (does: from plugin import cli)
    - cli_class : Main CLI class (does: from plugin.cli import CliPart)

    - gui_mod : GUI module of plugin
    - gui_class : Main Gui class

    - handler_mod : Handler module of plugin
    - handler_class : Main Handler Class

    - path : plugin absolute path
    - name : plugin name

  For CLI-only plugin, gui_* are equals to None
  For GUI-only plugin, cli_* are eqauls to None

  Handler is compulsory.
  """

  def __init__ (self, name, guiflag=True):
    u"""
    :param name: plugin's name, NOT plugin's path
    :type name: :obj:`unicode`
    """
    if isinstance(name, unicode):
      uname = name
      name = name.encode(ENCODING)
    elif isinstance(name, str) :
      uname = name.decode(ENCODING)

    if os.sep in name and Path(uname).isdir() :
      uplugin_path = Path(uname).abspath().parent
      module_name = Path(uname).abspath().name.encode(ENCODING)
      name = module_name
      uname = name.decode(ENCODING)
    else :
      uplugin_path = hardbook(u'extensions').abspath()
      module_name = 'plugins.%s' % name

    plugin_path = uplugin_path.encode(ENCODING)

    if plugin_path not in sys.path:
      sys.path.append(plugin_path)

    #try :
    # self.module = __import__(module_name, fromlist=['gui', 'cli', 'handler'])
    if guiflag:
      self.module = __import__(module_name, None, None, ['cli', 'gui', 'handler'])
    else:
      self.module = __import__(module_name, None, None, ['cli', 'handler'])
    #except ImportError :
      #uprint(tr_(u'Plugin "%(PLUGIN)s" invalid or not found in "%(PATH)s"') % dict(
            #PLUGIN=uname, PATH=uplugin_path))
      #sys.exit(1)

    self.handler_module = getattr(self.module, 'handler')
    self.handler_class = getattr(self.handler_module, 'HandlerPart')
    self.path = Path(self.handler_module.__file__.decode(ENCODING)).parent.abspath()
    self.name = uname

    # CLI
    try :
      cli_mod = getattr(self.module, 'cli')
    except AttributeError :
      self.cli_module = None
      self.cli_class = None
    else :
      self.cli_module = cli_mod
      self.cli_class = getattr(cli_mod, 'CliPart')

    # GUI
    try :
      gui_mod = getattr(self.module, 'gui')
    except AttributeError :
      self.gui_module = None
      self.gui_class = None
    else :
      self.gui_module = gui_mod
      self.gui_class = getattr(gui_mod, 'GuiPart')

      try :
        gui_pref_class = getattr(gui_mod, u'GuiPartPrefs')
      except AttributeError :
        self.gui_pref_class = None
      else :
        self.gui_pref_class = gui_pref_class
